package com.ease.platform.concurrent.service.impl;

import com.ease.concurrent.ConcurrentWholesaleCallback;
import com.ease.concurrent.ConcurrentWholesaleExecutor;
import com.ease.platform.authorization.service.impl.AbstractAuthorizationServiceImpl;
import com.ease.platform.usercontext.util.UserContextThreadLocal;
import com.ease.platform.usercontext.vo.UserContext;

public abstract class AbstractExecutiveConcurrentServiceImpl extends AbstractAuthorizationServiceImpl {

	protected ConcurrentWholesaleExecutor concurrentWholesaleExecutor;

	/**
	 * 
	 * @param <V>
	 * @param blockingMainThread
	 *            主线程是否阻塞
	 * @param taskSize
	 * @param concurrentTaskCallback
	 * @throws InterruptedException
	 */
	protected <V> void execute(boolean blockingMainThread, int taskSize, final ConcurrentWholesaleCallback<V> concurrentTaskCallback) throws InterruptedException {
		final UserContext userContext = UserContextThreadLocal.getUserContext();

		concurrentWholesaleExecutor.setBlockingMainThread(blockingMainThread);
		concurrentWholesaleExecutor.setTaskSize(taskSize);
		concurrentWholesaleExecutor.init();

		concurrentWholesaleExecutor.execute(new ConcurrentWholesaleCallback<Object>() {
			public Object execute(final int taskIndex) throws Throwable {
				UserContextThreadLocal.setUserContext(userContext);
				concurrentTaskCallback.execute(taskIndex);
				return null;
			}
		});
	}

	public <V> void blockingMainThread(int taskSize, final ConcurrentWholesaleCallback<V> concurrentTaskCallback) throws InterruptedException {
		this.execute(true, taskSize, concurrentTaskCallback);
	}

	public <V> void nonblockingMainThread(int taskSize, final ConcurrentWholesaleCallback<V> concurrentTaskCallback) throws InterruptedException {
		this.execute(false, taskSize, concurrentTaskCallback);
	}

	/**
	 * @return the concurrentWholesaleExecutor
	 */
	public ConcurrentWholesaleExecutor getConcurrentWholesaleExecutor() {
		return concurrentWholesaleExecutor;
	}

	/**
	 * @param concurrentWholesaleExecutor
	 *            the concurrentWholesaleExecutor to set
	 */
	public void setConcurrentWholesaleExecutor(ConcurrentWholesaleExecutor concurrentWholesaleExecutor) {
		this.concurrentWholesaleExecutor = concurrentWholesaleExecutor;
	}

}
